//  This file is part of Swordbible - http://www.swordwarrior.net
//  Copyright (C) 2003-2009 Manu Mital mital.manu@gmail.com

//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2, or (at your option)
//  any later version.

//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.

//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software Foundation,
//  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.


// ParallelBible.cpp : implementation file
//

#include <stdafx.h>
#include "SwordBible.h"
#include "ParallelBible.h"
#include "BibleForm.h"
#include "grid/GridCellRich.h"

// CParallelBible dialog

IMPLEMENT_DYNAMIC(CParallelBible, CPropertyPage)

CParallelBible::CParallelBible()
	: CPropertyPage(CParallelBible::IDD)
{

	


}

CParallelBible::~CParallelBible()
{
}

void CParallelBible::DoDataExchange(CDataExchange* pDX)
{
	CPropertyPage::DoDataExchange(pDX);
	DDX_GridControl(pDX, IDC_CUSTOM1, m_grid);
	
}


BEGIN_MESSAGE_MAP(CParallelBible, CPropertyPage)
//	ON_COMMAND(ID_PARALLEL_SELECTALL, OnSelectAll)
	ON_COMMAND(ID_PARALLEL_PRINT,OnPrint)
//	ON_COMMAND(ID_PARALLEL_COPY, OnCopy)
	ON_COMMAND(ID_PARALLEL_PREVIOUS,OnPrevious)
	ON_COMMAND(ID_PARALLEL_NEXT,OnNext)
	ON_COMMAND(ID_DROPDOWN_VERSIONS, OnShowVersions)
	ON_MESSAGE(ID_BIBLEPAGE_COMMAND,OnMainFrameCommand)
	ON_WM_SIZE()

	ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify)
   ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify)
  
  END_MESSAGE_MAP()


// CParallelBible message handlers

BOOL CParallelBible::OnInitDialog()
{
	CPropertyPage::OnInitDialog();

	for(int i = 0; i < CSwordBibleDoc::numBiblesAvailable; i++)
		BibleActive[i] = FALSE;

	// set the parameters of the grid

	 m_grid.SetDefaultCellType(RUNTIME_CLASS(CGridCellRich));
	
		 m_grid.SetEditable(0);   // Set the grid to be read only
		m_grid.EnableSelection(FALSE); // not allowing user selection of verses
		 m_grid.SetGridBkColor(RGB(255,255,255));
		 m_grid.SetFixedBkColor( RGB( 224, 238, 238 ));
		 m_grid.SetGridLines(GVL_HORZ);   // horizontal grid lines only
		 m_grid.SetFrameFocusCell(0); // cell with focus will not be highlighted with a border
		  m_grid.SetTrackFocusCell(FALSE);
         m_grid.SetFixedColumnSelection(FALSE);
		  m_grid.SetFixedRowSelection(FALSE);
		 m_grid.SetDefCellMargin(10);


		

    if (!m_wndFormatBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD
       | WS_VISIBLE | CBRS_TOP |  CBRS_FLYBY | CBRS_TOOLTIPS) ||
       !m_wndFormatBar.LoadToolBar(IDR_PARALLEL_TOOLBAR))
   {
      TRACE0("Failed to create toolbar\n");
      return -1;      // fail to create
   }

   // buttons size: 16
   // bitmaps:
   // enabled - IDB_TOOLBAR_NORMAL
   // hovered - IDB_TOOLBAR_HOT
   // disabled - IDB_TOOLBAR_DISABLED
   // transparent color RGB(255, 0, 255)
   m_wndFormatBar.LoadTCToolBar(24, IDB_BITMAP_PARALLEL,IDB_BITMAP_PARALLEL,
                              IDB_BITMAP_PARALLEL, RGB(255,255,255));




	// Position the control bars using RepositionBars. 
	RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);

	// Expand the size of the Toolbar window so all controls in it would fit
	
	CRect toolBarRect;
	CToolBarCtrl& formatBar = m_wndFormatBar.GetToolBarCtrl();
	formatBar.GetWindowRect(toolBarRect);
	ScreenToClient(toolBarRect);
	toolBarRect.left += 10  ;
	toolBarRect.right += 500  ;
	formatBar.MoveWindow(toolBarRect,TRUE);


	
	return TRUE;


}
void CParallelBible::OnSize(UINT nType, int cx, int cy)
{
	CPropertyPage::OnSize(nType, cx, cy);

	// resize the grid  control
	if( ::IsWindow( m_grid.GetSafeHwnd()))
	m_grid.SetWindowPos(NULL,10,40,cx-20,cy-50,SWP_NOZORDER | SWP_NOACTIVATE);

	


	

}

void CParallelBible::OnPrint()
{

	// only the active page should handle the message
		if(  !( ((CPropertySheet*) GetParent())->GetActivePage()   == this) )  
	  return;
	
		m_grid.Print();
  
	
}

void CParallelBible::OnPrevious()
{
  
	int chap = CSwordBibleDoc::key.Chapter();
	CSwordBibleDoc::key.Chapter(chap - 1);
	
	showText();

	CWnd * pWnd = AfxGetMainWnd();

	if(CSwordBibleDoc::notesSynch)
	{
	CNotesPage::ActiveMainFrameCommand = _T("BibleSynch");
	pWnd->SendMessageToDescendants(ID_NOTES_COMMAND,0,0);
	}

	if(CSwordBibleDoc::bottomSynch)
	{
	CBottomPage::ActiveMainFrameCommand = _T("BibleSynch");
	pWnd->SendMessageToDescendants(ID_COMMENTARY_COMMAND,0,0);
	}

  

}

void CParallelBible::OnNext()
{
    int chap = CSwordBibleDoc::Chapter();
	CSwordBibleDoc::key.Chapter(chap + 1);
	
	showText();

	CWnd * pWnd = AfxGetMainWnd();

	if(CSwordBibleDoc::notesSynch)
	{
	CNotesPage::ActiveMainFrameCommand = _T("BibleSynch");
	pWnd->SendMessageToDescendants(ID_NOTES_COMMAND,0,0);
	}

	if(CSwordBibleDoc::bottomSynch)
	{
	CBottomPage::ActiveMainFrameCommand = _T("BibleSynch");
	pWnd->SendMessageToDescendants(ID_COMMENTARY_COMMAND,0,0);
	}
  

}
/*
void CParallelBible::OnCopy(void) 
{

  // only the active page should handle the message
  if(  !( ((CPropertySheet*) GetParent())->GetActivePage()   == this) )  
	  return;

  m_grid.OnEditCopy();
}
*/

// displays the text in the rich edit box of the one year bible
void CParallelBible::showText()
{
	    	
		CString start;
		int height;
		sword::VerseKey key = CSwordBibleDoc::key;

		// get the chapter
			int chap = (CSwordBibleDoc::key).Chapter();
		
			// Get the book
			CString book = (CString) key.getBookAbbrev();
			int b = key.Book();
			start.Format(_T("%s %d:1"), book ,chap);

			

			// Clear and refresh the grid
			    m_grid.DeleteAllItems();

				// determine the number of columns needed
         	    int cols = 0;
                for(int i = 0; i < CSwordBibleDoc::numBiblesAvailable; i++)
					if(CSwordBibleDoc::pRTFBibleModule[i] && BibleActive[i] == TRUE)		cols++; 
				
			  	if(cols == 0) return; // nothing to display		
				cols++; // since we want one column as fixed
				m_grid.SetColumnCount(cols);
				m_grid.SetFixedColumnCount(1);
				
				FitColumns(cols);			 // expand the columns to fit the grid area

				
				  int numRows = 0;
				  // add row to the grid control
			      numRows++; m_grid.InsertRow(_T(""));
				  m_grid.SetFixedRowCount(1);


				// add the row headings containing the name of the bible
				CString head = CBiblePage::font.GetHeaderRTF();
         	    int j = 0;                               // zeroeth column is for verse keys
                for(int i = 0; i < CSwordBibleDoc::numBiblesAvailable; i++)
				if(CSwordBibleDoc::pRTFBibleModule[i] && BibleActive[i])
				{
					    
					m_grid.SetItemText(numRows - 1, j+1, head + 
						CSwordBibleDoc::pRTFBibleModule[i]->Description() + _T("}"));
						j++; 
				}



		

			for (key = (CStringA) start ; !key.Error() && key.Chapter() == chap && b ==  key.Book(); key++){

			 // add row to the grid control
			  numRows++; m_grid.InsertRow(_T(""));

        		  

            j = 0;
			m_grid.SetItemText(numRows - 1, j, head + key.getShortText() + _T("}"));
			j++;

             for(int i = 0; i < CSwordBibleDoc::numBiblesAvailable; i++)
			 if(CSwordBibleDoc::pRTFBibleModule[i] && BibleActive[i]) 
			{

				CSwordBibleDoc::pRTFBibleModule[i]->SetKey(key);             // set key to current verse

				chapText =  CBiblePage::font.GetHeaderRTF() + _T("\\cf2 ") + 
					(CString) CSwordBibleDoc::pRTFBibleModule[i]->RenderText() + _T("}");

				chapText.Replace(_T("\\par"), _T(" "));
				chapText.Replace(_T("\\cf6"), _T("\\cf9"));

				chapText.Replace(_T("<a href=\"\">*n"),  _T("\\cf5\\b *n"));
				chapText.Replace(_T("<a href=\"\">*x"),  _T("\\cf6\\b *x"));
				chapText.Replace(_T("</a>"), _T("\\cf2\\b0 "));
				chapText.Replace(_T("<a href=\"\">"),  _T(" "));
			
			               
				m_grid.SetItemFormat(numRows - 1, j, DT_WORDBREAK);
				m_grid.SetItemText(numRows - 1, j, chapText);
				if( j%2 == 0) m_grid.SetItemBkColour(numRows - 1,j,   RGB(240 ,248 ,255 )); // color alternate columns
				else m_grid.SetItemBkColour(numRows - 1,j,   RGB(255,255,245));
				

				// autosize the row
			   height = (int) (chapText.GetLength() * text_width * text_height/ (m_grid.GetColumnWidth(j) * 1.7)) ;
		     if(m_grid.GetRowHeight(numRows-1) < height)    m_grid.SetRowHeight(numRows -1, height);
				
            j++;
			} //done adding all the columns


			} // done adding all the rows
          
	

		
	

}


// expand all columns except the first one

void CParallelBible::FitColumns(int numCols)
{
	

    CRect rect;
	m_grid.GetWindowRect(&rect);
	m_grid.ExpandColumnsToFit(FALSE);

	m_grid.SetColumnWidth(0,100);
    
	for(int i = 1; i < numCols; i++)
		m_grid.SetColumnWidth(i, m_grid.GetColumnWidth(i) - 1);
	



}


void CParallelBible::OnChangeVersions()
{


	showText();
	
}

void CParallelBible::OnShowVersions()
{

	RECT rc;
    m_wndFormatBar.GetToolBarCtrl().GetItemRect(0,&rc);
	ClientToScreen(&rc); // TrackPopupMenu uses screen coords

   CMenu menu;
   menu.CreatePopupMenu();
   CMenu* pPopup = NULL;
   pPopup = &menu;

   if(pPopup == NULL) return;
   int dwSelectionMade;  

 
   // fill in the strings for different bible versions
	for(int i = 0; i < CSwordBibleDoc::numBiblesAvailable; i++)
		if(CSwordBibleDoc::pRTFBibleModule[i] != NULL)
		{
			         pPopup->AppendMenu(MF_STRING,ID_BIBLEVERSION_NAMES + i, (CString) CSwordBibleDoc::pRTFBibleModule[i]->Description());
					 if(BibleActive[i]) pPopup->CheckMenuItem(ID_BIBLEVERSION_NAMES + i,MF_CHECKED); 

		}


         dwSelectionMade =  pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON|TPM_RETURNCMD, 
         rc.left, rc.bottom + 4, this);

	
		int selection = dwSelectionMade;
		int base = ID_BIBLEVERSION_NAMES;
		int activate = selection - base;


	if(activate >= 0 && activate < CSwordBibleDoc::numBiblesAvailable) 
	{
		BibleActive[activate] = !BibleActive[activate];
		showText();

	}
    pPopup->DestroyMenu(); 


}






BOOL CParallelBible::OnSetActive()
{
	// set the font for the text and the text color in grid control
	CFont cellfont;
	cellfont.CreatePointFont(CBiblePage::font.text_facesize * 5, CBiblePage::font.text_facename ,NULL);	
	m_grid.SetFont(&cellfont);
	//m_grid.SetTextColor(  CColorMgr::RTFtoCOLORREF( CBiblePage::font.text_color ) );

		//calculate the width and height of chars

	

	HDC hDC = ::GetDC(NULL);
	HFONT hFontOld = (HFONT)SelectObject(hDC, cellfont.GetSafeHandle());
	TEXTMETRIC tm;
	GetTextMetrics(hDC, &tm);
	text_height  = tm.tmHeight + tm.tmExternalLeading;
	text_width =	tm.tmAveCharWidth ;
	SelectObject(hDC, hFontOld);
	::ReleaseDC(NULL, hDC);

   

    showText();


	return CPropertyPage::OnSetActive();
}

/*void CParallelBible::OnSelectAll()
{
		// only the active page should handle the message
  if(  !( ((CPropertySheet*) GetParent())->GetActivePage()   == this) )  
	  return;
  
  m_grid.OnEditSelectAll();

}*/

BOOL CParallelBible::OnToolTipNotify(UINT id, NMHDR *pNMHDR,   LRESULT *pResult)
{
    ASSERT(pNMHDR->code == TTN_NEEDTEXTA || pNMHDR->code == TTN_NEEDTEXTW);

     // if there is a top level routing frame then let it handle the message
     if (GetRoutingFrame() != NULL) return FALSE;

     // to be thorough we will need to handle UNICODE versions of the message also !!
     TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
     TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
     TCHAR szFullText[512];
     CString strTipText;
     UINT nID = pNMHDR->idFrom;

     if (pNMHDR->code == TTN_NEEDTEXTA && (pTTTA->uFlags & TTF_IDISHWND) ||
         pNMHDR->code == TTN_NEEDTEXTW && (pTTTW->uFlags & TTF_IDISHWND))
     {
          // idFrom is actually the HWND of the tool 
          nID = ::GetDlgCtrlID((HWND)nID);
     }

     if (nID != 0) // will be zero on a separator
     {
          AfxLoadString(nID, szFullText);
          strTipText=szFullText;

#ifndef _UNICODE
          if (pNMHDR->code == TTN_NEEDTEXTA)
          {
               lstrcpyn(pTTTA->szText, strTipText, sizeof(pTTTA->szText));
          }
          else
          {
               _mbstowcsz(pTTTW->szText, strTipText, sizeof(pTTTW->szText));
          }
#else
          if (pNMHDR->code == TTN_NEEDTEXTA)
          {
               _wcstombsz(pTTTA->szText, strTipText,sizeof(pTTTA->szText));
          }
          else
          {
               lstrcpyn(pTTTW->szText, strTipText, sizeof(pTTTW->szText));
          }
#endif

          *pResult = 0;

          // bring the tooltip window above other popup windows
          ::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0,SWP_NOACTIVATE|
               SWP_NOSIZE|SWP_NOMOVE|SWP_NOOWNERZORDER); return TRUE;
     }
      return FALSE;
}

LONG CParallelBible::OnMainFrameCommand(UINT, LONG)
{
	// only the active page should handle the message
	if(  !( ((CPropertySheet*) GetParent())->GetActivePage()   == this) )  
	  return 0L;
  
	if(CBiblePage::ActiveMainFrameCommand == _T("ShowChapter")) showText();
	
	 return 0L;
}





